
var fs = require('fs-extra');
var path = require('path');
var util = require('./util');

var rollup = require('rollup');
var resolve = require('rollup-plugin-node-resolve');
var commonjs = require('rollup-plugin-commonjs');
var json = require('rollup-plugin-json');
var uglify = require('rollup-plugin-uglify').uglify;
var package = require('../package.json');

// auto name out file
const name = (package.name.charAt(0) === '@') ? package.name.slice(1).replace('/', '-') : package.name.replace('/', '-');
// auto name amd id
const amdId = (package.name.charAt(0) === '@') ? package.name.slice(1).replace('/', '.') : package.name.replace('/', '.');
// input
const inputFile = 'src/index.ts';
// external module
const external = [];
// external globals module for browser
const globals = {}
// use package.dependencies and package.peerDependencies as default externals and golbal ids
if (package.dependencies) { for (const key in package.dependencies) { external.push(key); globals[key] = key; } }
if (package.peerDependencies) { for (const key in package.peerDependencies) { external.push(key); globals[key] = key; } }
// ------------------------------------------------
// clear dist
// ================================================

fs.removeSync(path.resolve(__dirname, '../dist'));
console.log(`Clear dist ...`);

// ------------------------------------------------
// method & variables
// ================================================
// input base name
const inputBaseName = path.basename(inputFile, '.ts')
const compliedInputFile = `dist/out-tsc/${inputBaseName}.js`;
async function build(input, output) {
    // create a bundle
    const bundle = await rollup.rollup(input);
    // generate code and a sourcemap
    await bundle.generate(output);
    // or write the bundle to disk
    await bundle.write(output);
}
const baseInputOption = {
    input: compliedInputFile,
    plugins: [
        resolve(),
        commonjs(),
        json()
    ]
}

// ------------------------------------------------
// complie typescript & typings
// ================================================

util.exec(`tsc -d --declarationDir dist --outDir dist/out-tsc`);
package.typings = `${inputBaseName}.d.ts`;

// ------------------------------------------------
// All bundle types
// ================================================

async function buildAll() {

    // ------------------------------------------------
    // UMD Module -> package.main
    // ================================================
    await build({
        ...baseInputOption,
        external: external
    }, {
        name: amdId,
        file: `dist/umd/${name}.js`,
        format: 'umd',
        exports: 'named',
        globals: globals
    });
    console.log(`${inputFile} -> dist/umd/${name}.js ...`);
    // update package
    package.main = `umd/${name}.js`;
    
    // ------------------------------------------------
    // ES Module -> package.module
    // ================================================
    
    await build({
        ...baseInputOption,
        external: external
    }, {
        file: `dist/esm5/${name}.js`,
        format: 'es'
    });
    console.log(`${inputFile} -> dist/esm5/${name}.js ...`);
    // update package
    package.module = `esm5/${name}.js`;
    
    // ------------------------------------------------
    // Full bundle -> single bundle file for browser
    // as default behavior, collect external and globals from package.peerDependencies
    // ================================================
    const peerExternal = [];
    const peerGlobals = {};
    if (package.peerDependencies) { for (const key in package.peerDependencies) { peerExternal.push(key); peerGlobals[key] = key; } }
    await build({
        ...baseInputOption,
        external: peerExternal
    }, {
        name: amdId,
        file: `dist/bundles/${name}.umd.js`,
        format: 'umd',
        exports: 'named',
        globals: peerGlobals
    });
    console.log(`${inputFile} -> dist/bundles/${name}.umd.js ...`);
    
    await build({
        ...baseInputOption,
        plugins: [
            ...baseInputOption.plugins,
            uglify()
        ],
        external: peerExternal
    }, {
        name: amdId,
        file: `dist/bundles/${name}.umd.min.js`,
        format: 'umd',
        exports: 'named',
        globals: peerGlobals
    });
    console.log(`${inputFile} -> dist/bundles/${name}.umd.min.js ...`);
    
    // ------------------------------------------------
    // write package.json and copy files
    // ================================================
    
    fs.outputJsonSync(path.resolve(__dirname, '../dist/package.json') , package, { spaces: '  ' });
    if (fs.existsSync(path.resolve(__dirname, '../LICENSE'))) {
        fs.copySync(path.resolve(__dirname, '../LICENSE'), path.resolve(__dirname, '../dist/LICENSE'));
    }
    if (fs.existsSync(path.resolve(__dirname, '../README.md'))) {
        fs.copySync(path.resolve(__dirname, '../README.md'), path.resolve(__dirname, '../dist/README.md'));
    }
    console.log(`Copy package.json, LICENSE, README.md ...`);
    
    // ------------------------------------------------
    // clear build
    // ================================================
    fs.removeSync(path.resolve(__dirname, '../dist/out-tsc'))
    // ------------------------------------------------
    // done
    // ================================================
    console.log(`Done !`);
}

buildAll();